import { SyncStorage } from "./SyncStorage";
import { log } from "cc";

import CryptoJs from "crypto-js";
import MD5 from "md5";
import { config } from "../config";

import { api } from "../config/api";

// 输出日志信息 最新修改为在taro配置uglify或terser控制 console
//
export let noConsole = "DEV";

export const jsonToParamsStr = (json_params) => {
  var params = Object.keys(json_params)
    .map(function (key) {
      // body...
      return (
        encodeURIComponent(key) + "=" + encodeURIComponent(json_params[key])
      );
    })
    .join("&");
  return params;
};
const request_data = {
  platform: "WEB",
  version: config.version,
};
export const request = (options) => {
  if (options.loading) {
  }
  //拼接url
  let fullUrl = api.ApiRootUrl + options.url;

  for (const key in options.data) {
    if (
      options.data.hasOwnProperty(key) &&
      (options.data[key] === undefined || options.data[key] == null)
    ) {
      delete options.data[key];
    }
  }

  const url = fullUrl + "?" + jsonToParamsStr(request_data);

  const _timeOut = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const error: any = new Error("请求超时");
        error.errCode = 504;
        error.errortext = "请求超时";
        reject(error);
      }, 60 * 1000);
    });
  };

  return Promise.race([
    fetch(url, {
      ...options,
      headers: {
        authorization: "Bearer " + SyncStorage.getValue("token"),
        "content-type": "application/json",
      },
    }),
    _timeOut(),
  ])

    .then((response: any) => response.json())
    .then((res) => {
      if (options.loading) {
      }
      if (noConsole != "production") {
        console.log(
          `${new Date().toLocaleString("zh", {
            hour12: false,
          })}【${fullUrl} 】【返回】`,
          res
        );
      }
      if (res && res.code != 0) {
        let tip = res.message ? "网络请求失败" + "," + res.code : res.status;
        console.log("error " + tip);
        if (res && res.code == 401) {
          // 写缓存咯
          //清缓存
          SyncStorage.setStorageSync("token", "");
          SyncStorage.setStorageSync("userInfo", "");
        }
        if (res && res.code == 404) {
          return null;
        }
        log(tip);
        return null;
        // 408 超时
      }
      return res;
    })

    .catch((err) => {
      log("网络异常");
      return null;
    });
};

export const urltoObj = (params) => {
  let obj = {};

  let parr = params.split("&"); // 将参数分割成数组 ["id = 1 ", " type = 2"]
  for (let i of parr) {
    // 遍历数组
    if (i !== "") {
      let arr = i.split("="); // 1） i id = 1   arr = [id, 1]  2）i type = 2  arr = [type, 2]
      obj[arr[0]] = arr[1]; // obj[arr[0]] = id, obj.id = 1   obj[arr[0]] = type, obj.type = 2
    }
  }
  return obj;
};

/**
 * 设置公共参数
 * @param {*} oldParams 参数 key-value形式的字符串
 * @return 新的参数
 */
export const getNewParams = (oldParams = "") => {
  var newParams = "";
  var MD5KEY = "hfu9CkqRMAVdhq2w";
  var token = SyncStorage.getValue("token"); //读取
  var currentDate = +new Date(); //获取到毫秒的时间戳，精确到毫秒
  var ip = SyncStorage.getValue("ip"); //读取
  var city = SyncStorage.getValue("city"); //读取

  newParams = oldParams + "&timestamp=" + currentDate;
  let digestStr = currentDate + MD5KEY;

  if (token) {
    newParams += "&token=" + token;
    digestStr += token;
  }
  if (ip) {
    newParams += "&ip=" + ip;
    digestStr += ip;
  }
  if (city) {
    newParams += "&city=" + city;
  }

  newParams += "&sign=" + MD5(digestStr);

  return newParams;
};

/**
 * request
 */
export const http = ({ url, data = {}, method = "GET" }) => {
  if (method.toLocaleUpperCase() == "POST") {
    // console.log(data)
    var newParams = getNewParams("");
    // 这里做了二次封装
    let bodyObj = Object.assign({ data }, urltoObj(newParams), {});

    let bodyStr = encryptUserInfoData(JSON.stringify(bodyObj));
    const bodyObj2 = { data: bodyStr };
    // var test = decryptUserInfoData(bodyStr)
    // console.log('解密：', test)
    return request({
      url: url,
      method: method,
      data: { ...bodyObj2 },
    });
  } else {
    let newParams2 = getNewParams("");
    let newParams = urltoObj(newParams2);

    return request({
      url: url,
      method: method,
      data: { ...data, ...newParams },
    });
  }
};

const defaultIv = "9189345332093662"; // 默认的key 偏移量

/**
 * 加密方法
 * @param: str 需要加密的字符
 * @param: key 密钥
 * @param: iv 密钥偏移量
 */
export const encryptUserInfoData = (
  encryptedData,
  sessionKey = config.aeskey
) => {
  // base64 decode
  const _sessionKey = sessionKey;
  const BLOCK_SIZE = 16;
  encryptedData = encodeURIComponent(encryptedData);

  let encode_encryptdata = "";
  let data = "";
  let encrypt = "";
  const keyStr = encParse(_sessionKey);
  const ivStr = encParse(defaultIv);
  try {
    // 加密
    if (typeof encryptedData == "string") {
      encrypt = encParse(encryptedData);
    } else {
      data = JSON.stringify(encryptedData);
      encrypt = encParse(data);
    }
    let encryptedStr = CryptoJs.AES.encrypt(encrypt, keyStr, {
      iv: ivStr,
      mode: CryptoJs.mode.CBC,
      padding: CryptoJs.pad.Pkcs7,
    });
    // 直接返回是 base64   128字节 encrypted.ciphertext.toString();
    encode_encryptdata = encryptedStr.toString();
  } catch (err) {
    console.log("encode_encryptdata", err);

    return "";
  }
  return encode_encryptdata;
};
/*
 * 处理密钥字符格式
 */
function encParse(key) {
  key = CryptoJs.enc.Utf8.parse(key);
  // key = CryptoJs.enc.Latin1.parse(key)
  return key;
}
export const decryptUserInfoData = (
  encryptedData,
  sessionKey = config.aeskey
) => {
  // base64 decode
  const _sessionKey = sessionKey;

  let decryptedStr = "";
  let decrypted = "";
  try {
    // 解密
    const keyStr = encParse(_sessionKey);
    const ivStr = encParse(defaultIv);

    // 判断str是否为base64,如果不是就要转base64，是了就不能再转
    // const flag = isBase64(encryptedData)
    // if (!flag) {
    //   // 转为base64之前要先转16进制
    //   const encrypted = CryptoJs.enc.Hex.parse(encryptedData)
    //   // 只有base64格式的字符才能被解密
    //   decrypted = CryptoJs.enc.Base64.stringify(encrypted)
    // } else {
    //   decrypted = encryptedData
    // }
    decrypted = encryptedData;

    var decoded = CryptoJs.AES.decrypt(decrypted, keyStr, {
      iv: ivStr,
      mode: CryptoJs.mode.CBC,
      padding: CryptoJs.pad.Pkcs7,
    });
    decryptedStr = decoded.toString(CryptoJs.enc.Utf8);
  } catch (err) {
    console.log(_sessionKey, "@@@@@@", err);
    return "";
  }
  return decodeURIComponent(decryptedStr);
  // return (decryptedStr)
};

/**
 * 判断是否是Base64格式的字符串
 */
function isBase64(str) {
  let reg =
    /^(([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=))|(([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{2}==))$/;
  console.log("isBase64", reg.test(str));
  return reg.test(str);
}
